local assets = {
	Asset("ATLAS", "images/inventoryimages/musha_armor_forest.xml"),
	Asset("IMAGE", "images/inventoryimages/musha_armor_forest.tex"),
	Asset("ANIM", "anim/musha_armor_forest.zip"),
	Asset("ANIM", "anim/musha_armor_forest_safe.zip"),
	Asset("ANIM", "anim/musha_armor_forest_danger.zip"),
	Asset("ANIM", "anim/musha_armor_forest_body.zip")
}

local function Updata(inst, display)
	if inst.components.musha_equipment:IsBroken() then
		inst.components.armor:SetAbsorption(0)
		return
	end

	local armor_value =
		inst.components.musha_equipment.currentlevel < 27 and inst.components.musha_equipment.currentlevel * 3 or
		math.min(inst.components.musha_equipment.currentlevel * 2 + 26, 85)
	local freeze_value =
		inst.components.musha_equipment.currentlevel < 25 and
		math.ceil(inst.components.musha_equipment.currentlevel * 0.1) * 10 + 10 or
		50

	inst.components.armor:SetAbsorption(armor_value * 0.01)

	inst.sanity_regen =
		inst.components.musha_equipment.currentlevel >= 15 and TUNING.DAPPERNESS_MED or TUNING.DAPPERNESS_SMALL

	inst.components.equippable.dapperness = inst.sanity_regen

	if display then
		if inst.components.musha_equipment.currentlevel < 15 then
			inst.components.talker:Say(
				string.format(
					STRINGS.MUSHA_ARMOR_FROST .. " (LV%d)\n" .. STRINGS.MUSHA_ARMOR .. " (%d)\n" .. STRINGS.MUSHA_ITEM_FREEZE .. "(%d)",
					inst.components.musha_equipment.currentlevel,
					armor_value,
					freeze_value
				)
			)
		else
			inst.components.talker:Say(
				string.format(
					STRINGS.MUSHA_ARMOR_FROST ..
						" (LV%d)\n" ..
							STRINGS.MUSHA_ARMOR ..
								" (%d)\n" .. STRINGS.MUSHA_ITEM_FREEZE .. "(%d)\n" .. STRINGS.MUSHA_ITEM_SANITY_REGEN .. "(Small)",
					inst.components.musha_equipment.currentlevel,
					armor_value,
					freeze_value
				)
			)
		end
	end
end

local function Change_Speed(inst, owner)
	if not owner then
		return
	end

	local hounded = TheWorld.components.hounded
	local danger = hounded ~= nil and (hounded:GetWarning() or hounded:GetAttacking())

	--[[ if inst.components.useableitem.inuse or not owner.sg:HasStateTag("book2") then
		owner.AnimState:OverrideSymbol("swap_body_tall", "musha_armor_forest_safe", "swap_body_tall")
		return
	end ]]
	--#TODO:威尔逊冰甲加速修复
	if danger then
		if not inst.on_shield then
			if inst.components.musha_equipment.currentlevel < 10 then
				inst.components.equippable.walkspeedmult = 1.15
			elseif inst.components.musha_equipment.currentlevel < 15 then
				inst.components.equippable.walkspeedmult = 1.2
			elseif inst.components.musha_equipment.currentlevel < 20 then
				inst.components.equippable.walkspeedmult = 1.25
			elseif inst.components.musha_equipment.currentlevel < 30 then
				inst.components.equippable.walkspeedmult = 1.3
			else
				inst.components.equippable.walkspeedmult = 1.35
			end
			owner.AnimState:OverrideSymbol("swap_body_tall", "musha_armor_forest_danger", "swap_body_tall")
		end
	else
		inst.components.equippable.walkspeedmult = 1.0
		if inst.in_danger then
			owner.AnimState:OverrideSymbol("swap_body_tall", "musha_armor_forest", "swap_body_tall")
		else
			owner.AnimState:OverrideSymbol("swap_body_tall", "musha_armor_forest_safe", "swap_body_tall")
		end
	end
	inst.in_danger = danger
end

local function OnEquip(inst, owner)
	inst.SoundEmitter:PlaySound("dontstarve/common/gem_shatter")
	Updata(inst)

	if inst.components.container ~= nil then
		inst.components.container:Open(owner)
	end

	owner.AnimState:OverrideSymbol("swap_body_tall", "musha_armor_forest", "swap_body_tall")
	owner.AnimState:OverrideSymbol("swap_body", "musha_armor_forest_body", "backpack")
	owner.AnimState:OverrideSymbol("swap_body", "musha_armor_forest_body", "swap_body")

	inst.speed_change =
		inst:DoPeriodicTask(
		0.2,
		function()
			Change_Speed(inst, owner)
		end
	)

	inst.freezefn = function(_, data)
		local attacker = data.attacker
		if data and attacker and attacker.components.freezable and attacker.components.combat then
			local fx = SpawnPrefab("icespike_fx_" .. math.random(4))
			local freeze_value
			if inst.components.musha_equipment.currentlevel < 25 then
				freeze_value = math.ceil(inst.components.musha_equipment.currentlevel * 0.1) * 0.1 + 0.1
			else
				freeze_value = 0.5
			end
			if math.random() < freeze_value then
				attacker.components.freezable:AddColdness(freeze_value)
				attacker.components.freezable:SpawnShatterFX()
				fx.Transform:SetScale(1, math.ceil(inst.components.musha_equipment.currentlevel * 0.1) * 0.25 + 0.5, 1)
				fx.Transform:SetPosition(attacker:GetPosition():Get())
			end
		end
	end

	inst:ListenForEvent("attacked", inst.freezefn, owner)
end

local function StopShield(inst, data)
	if not (data.statename == "shell_idle" or data.statename == "shell_hit" or data.statename == "shell_enter") then
		inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY).components.useableitem:StartUsingItem()
	end
end

local function Shield_Switch(inst, data)
	local owner = inst.components.inventoryitem.owner
	if not inst.on_shield then
		if inst.components.musha_equipment:IsBroken() then
			inst.components.talker:Say(STRINGS.MUSHA_ITEM_SHIELD_BROKEN .. "\n" .. STRINGS.MUSHA_ARMOR .. "(0)")
			inst.components.armor:SetAbsorption(0)
			return
		end
		inst.components.talker:Say(
			STRINGS.MUSHA_ITEM_SHIELD .. "\n" .. STRINGS.MUSHA_ARMOR .. "(100)\n" .. STRINGS.MUSHA_ITEM_COOL
		)
		inst.components.armor:SetAbsorption(1)
		inst.components.musha_equipment:StartConsuming()

		if owner then
			owner.sg:GoToState("shell_enter")
			owner.SoundEmitter:PlaySound("dontstarve/wilson/pickup_reeds")
		end
		if owner.components.sanity and not TheWorld.state.iswinter then
			inst:AddComponent("heater")
			inst.components.equippable.dapperness = inst.sanity_regen - 0.0005
			inst.components.heater:SetThermics(false, true)
			inst.components.heater.equippedheat = -2
			inst.SoundEmitter:PlaySound("dontstarve/common/gem_shatter")
		end
		inst:ListenForEvent("newstate", StopShield, owner)
	else
		if inst.components.heater then
			inst:RemoveComponent("heater")
		end
		inst.components.equippable.dapperness = inst.sanity_regen
		inst.components.musha_equipment:StopConsuming()

		inst:RemoveEventCallback("newstate", StopShield, owner)

		if owner then
			owner.sg:GoToState("idle")
			owner.SoundEmitter:PlaySound("dontstarve/wilson/pickup_reeds")
		end
		Updata(inst)
	end
	if inst.components.container ~= nil then
		inst.components.container:Open(owner)
	end
	inst.on_shield = not inst.on_shield
	inst.components.useableitem:StopUsingItem()
end

local function OnUnequip(inst, owner)
	if inst.on_shield then
		Shield_Switch(inst)
	end
	if inst.speed_change then
		inst.speed_change:Cancel()
		inst.speed_change = nil
	end
	inst.SoundEmitter:PlaySound("dontstarve/common/fireOut")

	owner.AnimState:ClearOverrideSymbol("swap_body_tall")
	owner.AnimState:ClearOverrideSymbol("swap_body")
	owner.AnimState:ClearOverrideSymbol("backpack")

	inst:RemoveEventCallback("attacked", inst.freezefn, owner)

	if inst.components.container ~= nil then
		inst.components.container:Close(owner)
	end
end

local function fn()
	local inst = CreateEntity()

	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()
	inst.entity:AddNetwork()

	MakeInventoryPhysics(inst)
	MakeInventoryFloatable(inst, nil, nil)

	inst:AddComponent("talker")
	inst.components.talker.fontsize = 30
	inst.components.talker.font = TALKINGFONT
	inst.components.talker.colour = Vector3(0.9, 1, 0.75, 1)
	inst.components.talker.offset = Vector3(0, 150, 0)
	inst.components.talker.symbol = "swap_object"

	inst.AnimState:SetBank("armor_wood")
	inst.AnimState:SetBuild("musha_armor_forest")
	inst.AnimState:PlayAnimation("anim")

	inst:AddTag("butterfly")
	inst:AddTag("fridge")
	inst:AddTag("backpack")
	inst:AddTag("aquatic")
	inst:AddTag("shell")
	inst:AddTag("musha_items")

	inst.foleysound = "dontstarve/movement/foley/shellarmour"

	inst.entity:SetPristine()

	if TheNet:GetIsClient() then
		inst.OnEntityReplicated = function(inst)
			inst.replica.container:WidgetSetup("backpack")
		end
		return inst
	end

	inst:AddComponent("equippable")
	inst.components.equippable:SetOnEquip(OnEquip)
	inst.components.equippable:SetOnUnequip(OnUnequip)

	inst:AddComponent("musha_equipment")
	inst.components.musha_equipment:SetUpgradable(false)
	inst.components.musha_equipment:InitMushaEquip("armor", 1050, 0.525)
	inst.components.musha_equipment:SetOnUpdataFn(Updata)
	inst.components.musha_equipment:SetOnBrokenFn(
		function()
			if inst.components.armor.absorb_percent ~= 0 then
				inst.components.armor:SetAbsorption(0)
				inst.components.talker:Say(
					STRINGS.MUSHA_ARMOR_BROKEN .. "\n" .. STRINGS.MUSHA_ARMOR .. " (0)\n" .. STRINGS.MUSHA_ITEM_DUR .. " (0)"
				)
			end
			inst.components.musha_equipment:StopConsuming()
		end
	)

	inst.components.inventoryitem.atlasname = "images/inventoryimages/musha_armor_forest.xml"

	if not MUSHA_SETTINGS.no_butterfly_shield then
		inst:AddComponent("useableitem")
		inst.components.useableitem:SetOnUseFn(Shield_Switch)
		inst.on_shield = false
	end

	inst:AddComponent("insulator")
	inst.components.insulator:SetInsulation(TUNING.INSULATION_LARGE)
	inst.components.insulator:SetSummer()

	inst:AddComponent("container")
	inst.components.container:WidgetSetup("backpack")

	inst.type = "ice"

	return inst
end

return Prefab("musha_armor_forest", fn, assets)
